﻿using Yxinmt.Interface;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.IO;

namespace Yxinmt.Controls
{
    public class WebView2 : BaseControl, IControl
    {
        Microsoft.Web.WebView2.Wpf.WebView2 _WebView2;

        public WebView2(Dictionary<string, object> property, IComponent component)
        {
            Property = property;
            _Component = component;

            _WebView2 = new Microsoft.Web.WebView2.Wpf.WebView2();
            _WebView2.DefaultBackgroundColor = System.Drawing.Color.FromArgb(0, 0, 0, 0);
            this.Element = _WebView2;

            InitSet();
            this.SetProperty();
            this.SetControlProperty(false, false);
        }

        private void SetProperty()
        {
        }

        protected override void SetProperty(string name, object value)
        {
            Microsoft.Web.WebView2.Wpf.WebView2 c = _WebView2;
            switch (name)
            {
                case "Name": c.Name = string.Concat("wbr_", (string)value); break;
                case "Height": c.Height = Convert.ToDouble(value); break;
                case "Width": c.Width = Convert.ToDouble(value); break;
                case "Dock": System.Windows.Controls.DockPanel.SetDock(c, this.GetDock((string)value)); break;
                case "ControlAlign": SetControlAlign((string)value); break;
                case "Visible": SetVisible((bool)value); break;
                case "GridRowColumn": SetGridRowColumn((string)value); break;
                case "Url": c.Source = new Uri(getUrl((string)value)); break;
                case "ZIndex": SetZIndex((int)value); break;
            }
        }

        string getUrl(string url)
        {
            if (string.IsNullOrEmpty(url) || !url.ToLower().StartsWith("http")) return url;

            return Utility.Common.AddUrlRandom(url);
        }

        public override void SetValue(object value)
        {
            if (value == null)
            {
                try
                {
                    _WebView2.NavigateToString(string.Empty);
                }
                catch
                {

                }
                return;
            }
            _WebView2.Source = new Uri(getUrl((string)value));
        }

        public override void EventLoad()
        {
            _WebView2.Loaded += _WebView2_Loaded;
            _WebView2.WebMessageReceived += _WebView2_WebMessageReceived;
        }

        public Action<Dictionary<string,object>> ReceiveMessage { get; set; }

        public void Send(string type, Dictionary<string, object> data=null)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            dict["type"] = type;
            dict["data"] = data;
            _WebView2.CoreWebView2.PostWebMessageAsString(Utility.Common.ToJson(dict));
        }

        public void Send(string type, string data)
        {
            Dictionary<string, object> dict = new Dictionary<string, object>();
            dict["type"] = type;
            dict["data"] = data;
            _WebView2.CoreWebView2.PostWebMessageAsString(Utility.Common.ToJson(dict));
        }

        private void _WebView2_WebMessageReceived(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebMessageReceivedEventArgs e)
        {
            string message = e.TryGetWebMessageAsString();
            if (string.IsNullOrEmpty(message)) return;

            var data = Utility.Common.JsonToDictionary(message);
            if (data == null) return;

            if (ReceiveMessage != null) ReceiveMessage(data);
        }

        public List<string> Filters { get; set; }
        public IJsToNative JsToNative { get; set; }

        private async void _WebView2_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            await _WebView2.EnsureCoreWebView2Async();
            if (Filters != null && Filters.Count > 0)
            {
                Filters.ForEach(f =>
                {
                    _WebView2.CoreWebView2.AddWebResourceRequestedFilter(f, Microsoft.Web.WebView2.Core.CoreWebView2WebResourceContext.All);
                });
                _WebView2.CoreWebView2.WebResourceRequested += CoreWebView2_WebResourceRequested;
            }
            _WebView2.CoreWebView2.Settings.IsZoomControlEnabled = false;
            if (JsToNative != null) _WebView2.CoreWebView2.AddHostObjectToScript("jsToNative", JsToNative);
//#if DEBUG
//#else
//            _WebView2.CoreWebView2.ContextMenuRequested += CoreWebView2_ContextMenuRequested;
//            _WebView2.CoreWebView2.Settings.AreDevToolsEnabled = false;
//#endif
        }

        public async void ExcuteScript(string jsCode, Action<Dictionary<string,object>> callback)
        {
            var res= await _WebView2.ExecuteScriptAsync(jsCode);
            var data = Utility.Common.JsonToDictionary(res);
            callback(data);
        }

        public Microsoft.Web.WebView2.Core.CoreWebView2 GetCoreWebView2()
        {
            return _WebView2.CoreWebView2;
        }

        public Action<Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs> SetResourceResponse { get; set; }

        private void CoreWebView2_WebResourceRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2WebResourceRequestedEventArgs e)
        {
            if (SetResourceResponse != null) SetResourceResponse(e);
        }

        private void CoreWebView2_ContextMenuRequested(object sender, Microsoft.Web.WebView2.Core.CoreWebView2ContextMenuRequestedEventArgs e)
        {
            e.Handled = true;
        }
    }

    public interface IJsToNative
    {

    }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [ComVisible(true)]
    public class JsToNative : IJsToNative
    {
    }
}
